package com.fauks.ssm.spring.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 定义切面,使用@Aspect标注该类为切面类
 */
@Component
@Aspect
public class LoggingAspect {

    //重用切入点表达式
    //定义切入点表达式
    @Pointcut("execution(* com.fauks.ssm.spring.aspectj.UserDaoImpl.add(..))")
    public void pointCutOperation() {

    }

    //使用定义的切入点表达式
    @Before("pointCutOperation()")
    public void testUsePointCut() {
    }


    //前置通知-->在方法执行前执行
    @Before("execution(public int com.fauks.ssm.spring.aspectj.UserDaoImpl.add(int,int))")
    public void testBefore(JoinPoint joinPoint) {
        //使用JoinPoint对象获取被代理方法相关信息
        System.out.println("testBefore===>" + joinPoint.getSignature().getName() + "-->开始执行");
    }

    //后置通知-->在连接点完成后执行，即连接点返回结果或抛出异常时都执行,但是该通知获取不到返回结果
    //@After("execution(public int com.fauks.demo.spring.aspectj.UserDaoImpl.div(int,int))")
    public void testAfter(JoinPoint joinPoint) {
        System.out.println("testBefore===>" + joinPoint.getSignature().getName() + "-->结束执行");
    }

    //返回通知-->只在方法正常返回结果时执行,使用returning指定返回结果的名称
    //@AfterReturning(value = "execution(public int com.fauks.demo.spring.aspectj.UserDaoImpl.add(int,int))", returning = "result")
    public void testAfterReturn(JoinPoint joinPoint, Object result) {
        System.out.println("AfterReturning===>" + joinPoint.getSignature().getName() + "-->结束执行，结果为:" + result);
    }

    //异常通知-->连接点抛出异常时执行，异常信息封装到throwing中，如果只关心一种异常可以将Throwable具体异常，如IOException
    //@AfterThrowing(value = "execution(public int com.fauks.demo.spring.aspectj.UserDaoImpl.div(int,int))", throwing = "ex")
    public void testAfterThrowing(JoinPoint joinPoint, Throwable ex) {
        System.out.println("testAfterThrowing===>" + joinPoint.getSignature().getName() + "-->出现异常，原因为:" + ex.toString());
    }

    //环绕通知-->可以全面控制连接点以及控制连接点是否执行
    //连接点的类型必须是ProceedingJoinPoint，允许控制何时执行连接点以及是否执行连接点
    @Around("execution(public int com.fauks.ssm.spring.aspectj.UserDaoImpl.div(int,int))")
    public int testAround(ProceedingJoinPoint joinPoint) {
        try {
            Object proceed = joinPoint.proceed();
            return (int) proceed;
        } catch (Throwable throwable) {
            //出现异常记录日志
            System.out.println("出现异常");
        } finally {
            System.out.println("后置异常无论什么情况都会执行");
        }
        return 0;
    }
}
